package com.ourteam.system.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;

import com.alibaba.fastjson.JSON;
import com.ourteam.system.dao.ISysDepartmentDAO;
import com.ourteam.system.dao.SysDepartment;
import com.ourteam.system.dao.SysDepartmentDAOQueryBean;
import com.ourteam.system.dao.SysUser;
import com.ourteam.system.dao.SysUserDepartmentRelate;
import com.ourteam.system.dao.SysUserDepartmentRelateDAOQueryBean;
import com.ourteam.system.domain.SystemDepartmentBean;
import com.ourteam.system.domain.SystemEventLogBean;
import com.ourteam.system.domain.SystemUserDepartmentRelateBean;

public class SysDepartmentServiceImpl extends AbstractSysDepartmentService {

	protected int doGetMaxSystemDepartmentSortIndex(long parentDepId) throws Exception {

		SysDepartmentDAOQueryBean queryBean = new SysDepartmentDAOQueryBean();

		queryBean.createCriteria().andParentIdEqualTo(parentDepId);

		return this.sysDepartmentDao.queryCount(queryBean) + 1;

	}

	protected void reSortSystemDepartmentSort(long[] parentDepIds) throws Exception {

		SysDepartmentDAOQueryBean queryBean = new SysDepartmentDAOQueryBean();

		for (int i = 0; i < parentDepIds.length; i++) {

			queryBean.clear();

			queryBean.createCriteria().andParentIdEqualTo(parentDepIds[i]);

			SysDepartment[] departments = this.sysDepartmentDao.query(queryBean);

			for (int j = 0; j < departments.length; j++) {
				departments[i].setSortIndex(j + 1);
			}

			this.sysDepartmentDao.batchUpdate(departments);
		}

	}

	/**
	 * 
	 * 
	 * @param aSystemDepartment
	 * 
	 * @model
	 * @throws BusinessErrorException
	 * @throws Exception
	 */
	// 添加一个新的系统部门
	@Override
	protected void doAddNewSystemDepartment(final com.ourteam.system.domain.SystemDepartmentBean aSystemDepartment)
			throws Exception {

		aSystemDepartment.setSortIndex(getMaxSystemDepartmentSortIndex(aSystemDepartment.getParentId()));

		sysDepartmentDao.insert(aSystemDepartment.convertToSysDepartment());

		SystemEventLogBean systemEventLog = new SystemEventLogBean();

		systemEventLog.setEventOperatorId(aSystemDepartment.getOperatorId());
		systemEventLog.setEventData(JSON.toJSONString(aSystemDepartment, true));
		systemEventLog.setEventSource("sysDepartment");
		Map<String, String> eventContent = new HashMap<String, String>();

		eventContent.put("dataType", "组织部门");
		eventContent.put("dataDesc", aSystemDepartment.getDepartmentName());

		this.systemEventLogService.addSystemEventLog("ADD_NEW_DATA", systemEventLog, eventContent);
	}

	/**
	 * 
	 * 
	 * @param aSystemDepartment
	 * 
	 * @model
	 * @throws BusinessErrorException
	 * @throws Exception
	 */
	// 修改一个系统部门
	@Override
	protected void doModifySystemDepartment(final com.ourteam.system.domain.SystemDepartmentBean aSystemDepartment)
			throws Exception {
		SysDepartment sysDepartment = aSystemDepartment.convertToSysDepartment();
		sysDepartmentDao.update(sysDepartment);

		SystemEventLogBean systemEventLog = new SystemEventLogBean();

		systemEventLog.setEventOperatorId(sysDepartment.getOperatorId());
		systemEventLog.setEventData(JSON.toJSONString(sysDepartment, true));
		systemEventLog.setEventSource("sysDepartment");
		Map<String, String> eventContent = new HashMap<String, String>();

		eventContent.put("dataType", "组织部门");
		eventContent.put("dataDesc", sysDepartment.getDepartmentName());

		this.systemEventLogService.addSystemEventLog("MODIFY_DATA", systemEventLog, eventContent);

		updateUserDepartmentInfo(aSystemDepartment.getId());
	}

	/**
	 * 
	 * 
	 * @param aSystemDepartmentId
	 * 
	 * @model
	 * @throws BusinessErrorException
	 * @throws Exception
	 */
	@Override
	protected com.ourteam.system.domain.SystemDepartmentBean doGetSystemDepartmentById(final long aSystemDepartmentId)
			throws Exception {

		SysDepartment department = this.sysDepartmentDao.findById(aSystemDepartmentId);

		return department != null ? new SystemDepartmentBean(department) : null;

	}

	/**
	 * 
	 * 
	 * @param aSystemDepartmentIds
	 * 
	 * @model
	 * @throws BusinessErrorException
	 * @throws Exception
	 */
	// 删除一个系统部门
	@Override
	protected void doDeleteSystemDepartments(final long[] aSystemDepartmentIds, long operatorId) throws Exception {

		SysDepartmentDAOQueryBean queryBean = new SysDepartmentDAOQueryBean();

		queryBean.createCriteria().andIdIn(aSystemDepartmentIds);

		SysDepartment[] departments = this.sysDepartmentDao.query(queryBean);

		List<Long> parentDepIds = new ArrayList<>();

		for (int i = 0; i < departments.length; i++) {

			SysDepartment department = departments[i];

			if (parentDepIds.contains(department.getParentId()) == false) {
				parentDepIds.add(department.getParentId());
			}

			SystemEventLogBean systemEventLog = new SystemEventLogBean();

			systemEventLog.setEventOperatorId(operatorId);

			systemEventLog.setEventSource("sysDepartment");
			Map<String, String> eventContent = new HashMap<String, String>();

			eventContent.put("dataType", "组织部门");
			eventContent.put("dataDesc", department.getDepartmentName());

			this.systemEventLogService.addSystemEventLog("DELETE_DATA", systemEventLog, eventContent);

		}

		sysDepartmentDao.delete(queryBean);

		reSortSystemDepartmentSort(ArrayUtils.toPrimitive(parentDepIds.toArray(new Long[parentDepIds.size()])));

	}

	/**
	 * 
	 * 
	 * @param queryBean
	 * 
	 * @model
	 * @throws BusinessErrorException
	 * @throws Exception
	 */
	@Override
	protected com.ourteam.system.domain.SystemDepartmentBean[] doQuerySystemDepartments(
			final com.ourteam.system.dao.SysDepartmentDAOQueryBean queryBean) throws Exception {

		return SystemDepartmentBean.toArray(this.sysDepartmentDao.query(queryBean));

	}

	/**
	 * 
	 * 
	 * @param queryBean
	 * 
	 * @model
	 * @throws BusinessErrorException
	 * @throws Exception
	 */
	// 查询系统部门的数量
	@Override
	protected int doQuerySystemDepartmentCount(final com.ourteam.system.dao.SysDepartmentDAOQueryBean queryBean)
			throws Exception {
		return this.sysDepartmentDao.queryCount(queryBean);
	}

	/**
	 * 
	 * 
	 * @param aSystemUserDepartment
	 * 
	 * @model
	 * @throws BusinessErrorException
	 * @throws Exception
	 */
	@Override
	protected void doSetSystemUserDepartment(
			final com.ourteam.system.domain.SystemUserDepartmentRelateBean aSystemUserDepartment) throws Exception {

		SysUserDepartmentRelateDAOQueryBean queryBean = new SysUserDepartmentRelateDAOQueryBean();

		queryBean.createCriteria().andSysUserIdEqualTo(aSystemUserDepartment.getSysUserId())
				.andSysDepartmentIdEqualTo(aSystemUserDepartment.getSysDepartmentId());

		this.sysUserDepartmentRelateDao.synchronize(
				new SysUserDepartmentRelate[] { aSystemUserDepartment.convertToSysUserDepartmentRelate() }, queryBean);

		queryBean.clear();

		queryBean.createCriteria().andSysUserIdEqualTo(aSystemUserDepartment.getSysUserId());

		SysUserDepartmentRelate[] userDepartmentRelates = this.sysUserDepartmentRelateDao.query(queryBean);

		SysUser sysUser = this.sysUserDao.findById(aSystemUserDepartment.getSysUserId());

		List<String> depList = new ArrayList<>();

		for (int i = 0; i < userDepartmentRelates.length; i++) {

			SysUserDepartmentRelate sysUserDepartmentRelate = userDepartmentRelates[i];

			List<String> userDepList = new ArrayList<>();

			userDepList.add(sysUserDepartmentRelate.getDepartmentName());

			sysUser.setUserDepartmentRole(sysUserDepartmentRelate.getDepartmentRole());

			SysDepartment department = this.sysDepartmentDao.findById(sysUserDepartmentRelate.getSysDepartmentId());

			long parentId = department.getParentId();

			while (parentId != 0) {
				department = this.sysDepartmentDao.findById(parentId);
				userDepList.add(0, department.getDepartmentName());
				parentId = department.getParentId();
			}
			depList.add(StringUtils.join(userDepList, " > "));
		}

		sysUser.setUserDepartment(StringUtils.join(depList, ";"));

		this.sysUserDao.update(sysUser);
	}

	protected void updateUserDepartmentInfo(long depId) throws Exception {
		SysUserDepartmentRelateDAOQueryBean queryBean = new SysUserDepartmentRelateDAOQueryBean();

		queryBean.createCriteria().andSysDepartmentIdEqualTo(depId);

		SysUserDepartmentRelate[] userDepartmentRelates = this.sysUserDepartmentRelateDao.query(queryBean);

		for (int i = 0; i < userDepartmentRelates.length; i++) {
			SysUserDepartmentRelate sysUserDepartmentRelate = userDepartmentRelates[i];

			SysUser sysUser = this.sysUserDao.findById(sysUserDepartmentRelate.getSysUserId());

			List<String> userDepList = new ArrayList<>();

			userDepList.add(sysUserDepartmentRelate.getDepartmentName());

			sysUser.setUserDepartmentRole(sysUserDepartmentRelate.getDepartmentRole());

			SysDepartment department = this.sysDepartmentDao.findById(sysUserDepartmentRelate.getSysDepartmentId());

			long parentId = department.getParentId();

			while (parentId != 0) {
				department = this.sysDepartmentDao.findById(parentId);
				userDepList.add(0, department.getDepartmentName());
				parentId = department.getParentId();
			}
			sysUser.setUserDepartment(StringUtils.join(userDepList, " > "));

			this.sysUserDao.update(sysUser);

		}
	}

	/**
	 * 
	 * 
	 * @param aSystemUserDepartmentId
	 * 
	 * @model
	 * @throws BusinessErrorException
	 * @throws Exception
	 */
	@Override
	protected com.ourteam.system.domain.SystemUserDepartmentRelateBean doGetSystemUserDepartmentById(
			final long aSystemUserDepartmentId) throws Exception {

		SysUserDepartmentRelate department = this.sysUserDepartmentRelateDao.findById(aSystemUserDepartmentId);

		return department != null ? new SystemUserDepartmentRelateBean(department) : null;
	}

	/**
	 * 
	 * 
	 * @param queryBean
	 * 
	 * @model
	 * @throws BusinessErrorException
	 * @throws Exception
	 */
	@Override
	protected com.ourteam.system.domain.SystemUserDepartmentRelateBean[] doQuerySystemUserDepartments(
			final com.ourteam.system.dao.SysUserDepartmentRelateDAOQueryBean queryBean) throws Exception {

		return SystemUserDepartmentRelateBean.toArray(this.sysUserDepartmentRelateDao.query(queryBean));
	}

	/**
	 * 
	 * 
	 * @param queryBean
	 * 
	 * @model
	 * @throws BusinessErrorException
	 * @throws Exception
	 */
	// 查询系统用户部门数
	@Override
	protected int doQuerySystemUserDepartmentCount(
			final com.ourteam.system.dao.SysUserDepartmentRelateDAOQueryBean queryBean) throws Exception {

		return this.sysUserDepartmentRelateDao.queryCount(queryBean);
	}

	/**
	 * 
	 * 
	 * @param aSystemUserDepartmentIds
	 * 
	 * @model
	 * @throws BusinessErrorException
	 * @throws Exception
	 */
	// 删除系统部门
	@Override
	protected void doDeleteSystemUserDepartments(final long[] aSystemUserDepartmentIds) throws Exception {
		
		if(ArrayUtils.isEmpty(aSystemUserDepartmentIds)) {
			return;
		}

		SysUserDepartmentRelateDAOQueryBean queryBean = new SysUserDepartmentRelateDAOQueryBean();

		queryBean.createCriteria().andIdIn(aSystemUserDepartmentIds);

		sysUserDepartmentRelateDao.delete(queryBean);

	}

	protected void doSetSystemDepartmentSortIndex(long depId, int sortIndex, long operatorId) throws Exception {

		if (sortIndex < 0) {
			logger.warn("The Sort Index Must Gret Then 0");
			return;
		}

		SysDepartment sysDepartment = this.sysDepartmentDao.findById(depId);

		if (sysDepartment == null) {
			logger.warn("Can Not Found The System Department[" + depId + "]");
			return;
		}

		SysDepartmentDAOQueryBean queryBean = new SysDepartmentDAOQueryBean();

		queryBean.createCriteria().andParentIdEqualTo(sysDepartment.getParentId()).andIdNotEqualTo(depId);

		queryBean.setSortProperty(ISysDepartmentDAO.SortIndex);

		SysDepartment[] sysDepartments = sysDepartmentDao.query(queryBean);

		if (sortIndex > sysDepartments.length + 1) {
			logger.warn("The Sort Index Must Less than " + sysDepartments.length + 1);
			return;
		}

		if (sortIndex > 0) {
			sysDepartments = (SysDepartment[]) ArrayUtils.add(sysDepartments, sortIndex - 1, sysDepartment);

		} else {
			sysDepartments = (SysDepartment[]) ArrayUtils.add(sysDepartments, sysDepartment);
		}

		for (int i = 0; i < sysDepartments.length; i++) {
			sysDepartments[i].setSortIndex(new Integer(i + 1));
			if (depId == sysDepartments[i].getId()) {

				SystemEventLogBean systemEventLog = new SystemEventLogBean();

				systemEventLog.setEventOperatorId(operatorId);
				systemEventLog.setEventData(JSON.toJSONString(sysDepartments[i], true));
				systemEventLog.setEventSource("sysDepartment");
				Map<String, String> eventContent = new HashMap<String, String>();

				eventContent.put("dataType", "组织部门");
				eventContent.put("dataDesc", sysDepartments[i].getDepartmentName());

				this.systemEventLogService.addSystemEventLog("MODIFY_DATA", systemEventLog, eventContent);
			}
		}

		sysDepartmentDao.batchUpdate(sysDepartments);

	}

}